//
//  clock_lib.c
//  electronic_clock
//
//  Created by 傅凯 on 2018/10.
//  Copyright © 2018年 赛博智能车实验室. All rights reserved.
//

#include "clock_lib.h"


/********时间部分********/

//闰年判断
//在主函数状态机中运行
void LeapYearJudge(ClockNode *clk)
{
    //能被400整除或者能被4整除且不能被100整除的年份为闰年
    if((clk->year % 400 ==0) || (clk->year % 4 == 0 && clk->year % 100 != 0))
    {
        clk->LeapYearStatus = LEAP_YEAR;
    }
    else
    {
        clk->LeapYearStatus = NOT_LEAP_YEAR;
    }
}

//时钟工作函数
//放在中断中
//sec_times:中断一秒钟计数
void ClockWork(ClockNode *clk, int sec_times)
{
    static int times = 0;

    switch(clk->ClockWorkStatus)
    {
        case CLOCK_NORMAL:  //时钟正常工作
            ++times;
            if(times == sec_times)   //达到中断一秒钟计数次数
            {
                times = 0;
                clk->second++;
            }
            if(clk->second > 59)
            {
                clk->second = 0;
                clk->minute++;
            }
            if(clk->minute > 59)
            {
                clk->minute = 0;
                clk->hour++;
            }
            if(clk->hour > 23)
            {
                clk->hour = 0;
                clk->date++;
                clk->Week++;
                switch(clk->month)
                {
                    //大月
                    case 1://一月
                    case 3://三月
                    case 5://五月
                    case 7://七月
                    case 8://八月
                    case 10://十月
                    case 12://十二月
                        if(clk->date > 31)
                        {
                            clk->date = 1;
                        }
                        break;

                    //小月
                    case 4://四月
                    case 6://六月
                    case 9://九月
                    case 11://十一月
                        if(clk->date > 30)
                        {
                            clk->date = 1;
                        }
                        break;

                    //二月
                    case 2://二月
                        switch(clk->LeapYearStatus)
                        {
                            case LEAP_YEAR: //闰年
                                    if(clk->date > 29)
                                    {
                                        clk->date = 1;
                                    }
                                    break;
                            case NOT_LEAP_YEAR: //不是闰年
                                    if(clk->date > 28)
                                    {
                                        clk->date = 1;
                                    }
                                    break;
                        }
                        break;
                }
                if(clk->Week > Sunday)
                {
                    clk->Week = Monday;
                }
            }
            break;

        case CLOCK_SETTING: //设置时间
            times = 0;
            break;
    }
}

//时钟时间设置部分
//时间加，每次增加1
void TimeAddSet(ClockNode *clk)
{
    switch(clk->TimeSet)
    {
        case SECOND_SET:
                clk->second++;
                if(clk->second == 60)
                {
                    clk->second = 0;
                }
                break;
        case MINUTE_SET:
                clk->minute++;
                if(clk->minute == 60)
                {
                    clk->minute = 0;
                }
                break;
        case HOUR_SET:
                clk->hour++;
                if(clk->hour == 24)
                {
                    clk->hour = 0;
                }
                break;
        case DATE_SET:
                clk->date++;
                switch(clk->month)
                {
                    //大月
                    case 1://一月
                    case 3://三月
                    case 5://五月
                    case 7://七月
                    case 8://八月
                    case 10://十月
                    case 12://十二月
                        if(clk->date > 31)
                        {
                            clk->date = 1;
                        }
                        break;

                    //小月
                    case 4://四月
                    case 6://六月
                    case 9://九月
                    case 11://十一月
                        if(clk->date > 30)
                        {
                            clk->date = 1;
                        }
                        break;

                    //二月
                    case 2://二月
                        switch(clk->LeapYearStatus)
                        {
                            case LEAP_YEAR: //闰年
                                    if(clk->date > 29)
                                    {
                                        clk->date = 1;
                                    }
                                    break;
                            case NOT_LEAP_YEAR: //不是闰年
                                    if(clk->date > 28)
                                    {
                                        clk->date = 1;
                                    }
                                    break;
                        }
                        break;
                }
                break;
        case MONTH_SET:
                clk->month++;
                if(clk->month > 12)
                {
                    clk->month = 1;
                }
                break;
        case YEAR_SET:
                clk->year++;
                if(clk->year > 2100)
                {
                    clk->year = 2100;
                }
                break;
        case WEEK_SET:
                clk->Week++;
                if(clk->Week > Sunday)
                {
                    clk->Week = Monday;
                }
                break;
    }
}
//时间减，每次减1
void TimeDecreaseSet(ClockNode *clk)
{
    switch(clk->TimeSet)
    {
        case SECOND_SET:
                clk->second--;
                if(clk->second < 0)
                {
                    clk->second = 59;
                }
                break;
        case MINUTE_SET:
                clk->minute--;
                if(clk->minute < 0)
                {
                    clk->minute = 59;
                }
                break;
        case HOUR_SET:
                clk->hour--;
                if(clk->hour < 0)
                {
                    clk->hour = 23;
                }
                break;
        case DATE_SET:
                clk->date--;
                switch(clk->month)
                {
                    //大月
                    case 1://一月
                    case 3://三月
                    case 5://五月
                    case 7://七月
                    case 8://八月
                    case 10://十月
                    case 12://十二月
                        if(clk->date < 1)
                        {
                            clk->date = 31;
                        }
                        break;

                    //小月
                    case 4://四月
                    case 6://六月
                    case 9://九月
                    case 11://十一月
                        if(clk->date < 1)
                        {
                            clk->date = 30;
                        }
                        break;

                    //二月
                    case 2://二月
                        switch(clk->LeapYearStatus)
                        {
                            case LEAP_YEAR: //闰年
                                    if(clk->date < 1)
                                    {
                                        clk->date = 29;
                                    }
                                    break;
                            case NOT_LEAP_YEAR: //不是闰年
                                    if(clk->date < 1)
                                    {
                                        clk->date = 28;
                                    }
                                    break;
                        }
                        break;
                }
                break;
        case MONTH_SET:
                clk->month--;
                if(clk->month < 1)
                {
                    clk->month = 12;
                }
                break;
        case YEAR_SET:
                clk->year--;
                if(clk->year < 1900)
                {
                    clk->year = 1900;
                }
                break;
        case WEEK_SET:
                clk->Week--;
                if(clk->Week < Monday)
                {
                    clk->Week = Sunday;
                }
                break;
    }
}



/********闹钟部分********/

//闹钟工作
//在中断中运行
//sec_times:中断一秒钟计数
//alarm_work_sec:闹钟响铃延时时间
void AlarmWork(ClockNode *clk, int sec_times, int alarm_work_sec)
{
    static int times=0, sec=0;

    switch(clk->AlarmClockWorkStatus)
    {
        case ALARM_STOP: //闹钟关闭
            times = 0;
            sec = 0;
            break;
        case ALARM_START://闹钟开启
            if(clk->minute == clk->alarm_minute && clk->hour == clk->alarm_hour && clk->second == 0)
            {
                clk->AlarmClockWorkStatus = ALARM_WORKING;
            }
            break;
        case ALARM_WORKING://闹钟正在响铃
            times++;
            if(times == sec_times)
            {
                times = 0;
                sec++;
            }
            if(sec == alarm_work_sec)
            {
                sec = 0;
                times = 0;
                clk->AlarmClockWorkStatus = ALARM_START;
            }
            break;
    }
}

//闹钟时间设置
//闹钟时间加1
void AlarmAddSet(ClockNode *clk)
{
    switch(clk->AlarmTimeSet)
    {
        case ALARM_MINUTE_SET:
            clk->alarm_minute++;
            if(clk->alarm_minute > 59)
            {
                clk->alarm_minute = 0;
            }
            break;
        case ALARM_HOUR_SET: 
            clk->alarm_hour++;
            if(clk->alarm_hour > 23)
            {
                clk->alarm_hour = 0;
            }
            break;
    }
}
//闹钟时间减1
void AlarmDecreaseSet(ClockNode *clk)
{
    switch(clk->AlarmTimeSet)
    {
        case ALARM_MINUTE_SET:
            clk->alarm_minute--;
            if(clk->alarm_minute < 0)
            {
                clk->alarm_minute = 59;
            }
            break;
        case ALARM_HOUR_SET: 
            clk->alarm_hour--;
            if(clk->alarm_hour < 0)
            {
                clk->alarm_hour = 23;
            }
            break;
    }
}

/********秒表部分********/

//秒表工作函数
//millisecond_times:中断1ms计数
void StopWatchWork(ClockNode *clk, int millisecond_times)
{
    static int times = 0;

    switch(clk->StopWatchStatus)
    {
        case WATCH_STOP://秒表停止工作
            times = 0;//计数清空
            clk->stop_millisecond = 0;
            clk->stop_second = 0;
            clk->stop_minute = 0;
            clk->stop_hour = 0;
            break;
        case WATCH_START: //秒表开始计时
            times++;
            if(times == millisecond_times)
            {
                times = 0;
                clk->stop_millisecond++;
            }
            if(clk->stop_millisecond > 99)
            {
                clk->stop_millisecond = 0;
                clk->stop_second++;
            }
            if(clk->stop_second > 59)
            {
                clk->stop_second = 0;
                clk->stop_minute++;
            }
            if(clk->stop_minute > 59)
            {
                clk->stop_minute = 0;
                clk->stop_hour++;
            }
            break;
        case WATCH_PAUSE://秒表暂停
            break;
    }
}

/********计时器部分********/

//计时器工作函数
//sec_times:定时器中断一秒计数
//timer_alarm_time:定时器报警时长
void TimerWork(ClockNode *clk, int sec_times, int timer_alarm_time)
{
    static int times = 0, alarm_times = 0, alarm_sec = 0;

    switch(clk->TimerWorkStatus)
    {
        case TIMER_STOP://计时器停止
            times = 0;
			alarm_times = 0;
			alarm_sec = 0;
            break;
        case TIMER_START://计时器启动
            times++;
            if(times == sec_times)//1s计时
			{
				times = 0;
				clk->timer_second--;
			}
			if(clk->timer_second==0 && clk->timer_minute==0 && clk->timer_hour==0)
			{
				clk->TimerWorkStatus = TIMER_ALARM;
			}
			else
			{
				if(clk->timer_second < 0)
				{
					clk->timer_second = 59;
					clk->timer_minute--;
				}
				if(clk->timer_minute < 0)
				{
					clk->timer_minute = 59;
					clk->timer_hour--;
				}
			}
			
            break; 
        case TIMER_ALARM://计时器报警
            alarm_times++;
            if(alarm_times == sec_times)
            {
                alarm_times = 0;
                alarm_sec++;
            }
            if(alarm_sec == timer_alarm_time)
            {
                alarm_times = 0;
                alarm_sec = 0;
                clk->TimerWorkStatus = TIMER_STOP;
            }
            break;
    }
}

//计时器时间设置
//计时器时间加1
void TimerAddSet(ClockNode *clk)
{
    switch(clk->TimerSet)
    {
        case TIMER_SECOND_SET://计时器秒设置
            clk->timer_second++;
            if(clk->timer_second > 59)
            {
                clk->timer_second = 0;
            }
            break;
        case TIMER_MINUTE_SET://计时器分设置
            clk->timer_minute++;
            if(clk->timer_minute > 59)
            {
                clk->timer_minute = 0;
            }
            break;
        case TIMER_HOUR_SET://计时器时设置
            clk->timer_hour++;
            if(clk->timer_hour > 23)
            {
                clk->timer_hour = 0;
            }
            break;
    }
}
//计时器时间减1
void TimerDecreaseSet(ClockNode *clk)
{
    switch(clk->TimerSet)
    {
        case TIMER_SECOND_SET://计时器秒设置
            clk->timer_second--;
            if(clk->timer_second < 0)
            {
                clk->timer_second = 59;
            }
            break;
        case TIMER_MINUTE_SET://计时器分设置
            clk->timer_minute--;
            if(clk->timer_minute < 0)
            {
                clk->timer_minute = 59;
            }
            break;
        case TIMER_HOUR_SET://计时器时设置
            clk->timer_hour--;
            if(clk->timer_hour < 0)
            {
                clk->timer_hour = 23;
            }
            break;
    }
}

